﻿using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LettuceEncrypt.Extensions.AliDns;

public class AlibabaCloudDnsClient
{
    private readonly IOptionsMonitor<AlibabaCloudOptions> _options;
    private readonly ILogger _logger;

    public AlibabaCloudDnsClient(IOptionsMonitor<AlibabaCloudOptions> options,
        ILogger<AlibabaCloudDnsClient> logger)
    {
        _options = options;
        _logger = logger;
    }

    private AlibabaCloudOptionsValidator OptionsValidator = new AlibabaCloudOptionsValidator();
    
    private AlibabaCloud.SDK.Alidns20150109.Client GetClient(AlibabaCloudOptions options)
    {
        var result = OptionsValidator.Validate(options);

        if(result.IsValid == false)
        {
            throw new OptionsValidationException(
                nameof(AlibabaCloudOptions), 
                typeof(AlibabaCloudOptions), 
                result.Errors.Select(x => x.ErrorMessage));
        }

        var config = new AlibabaCloud.OpenApiClient.Models.Config
        {
            AccessKeyId = options.AccessKeyId,
            AccessKeySecret = options.AccessKeySecret,
            Endpoint = options.Address,
        };

        return new AlibabaCloud.SDK.Alidns20150109.Client(config);
    }

    private AlibabaCloud.SDK.Alidns20150109.Client AliDnsClient => GetClient(_options.CurrentValue);

    public async Task<string?> AddDomainRecordAsync(string domain, string rr, string type, string value, CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();

        var request = new AlibabaCloud.SDK.Alidns20150109.Models.AddDomainRecordRequest
        {
            DomainName = domain,
            RR = rr,
            Type = type,
            Value = value
        };

        var resp = await AliDnsClient.AddDomainRecordAsync(request);

        _logger.LogInformation("Received [AddDomainRecord] {RequestId}: {@Response}", resp.Body.RequestId, resp);

        if (resp.StatusCode == 200)
        {
            return resp.Body.RecordId;
        }

        return null;
    }

    public async Task<string?> DeleteDomainRecordAsync(string recordId, CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();

        var resp = await AliDnsClient.DeleteDomainRecordAsync(new AlibabaCloud.SDK.Alidns20150109.Models.DeleteDomainRecordRequest
        {
            RecordId = recordId,
        });

        _logger.LogInformation("Received [DeleteDomainRecord] {RequestId}: {@Response}", resp.Body.RequestId, resp);

        if (resp.StatusCode == 200)
        {
            return resp.Body.RecordId;
        }

        return null;
    }
}
